import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core'

import { PageService } from '@shared/services/page.service'
import { ETabScrollStatus } from '@shared/enums'
import { CommonAcquirerService } from '@shared/services/acquirer.service'
import { EAuditConfigType, AuditConfig, IUpdateAcquirerAudit } from '@shared/interfaces/acquirer'
import { DetailTabClass } from '@shared/classes/DetailTabClass'
import { AcquirerService } from '../../acquirer.service'
import { ActivatedRoute } from '@angular/router'
import { IBaseInfoColumn } from '@shared/interfaces/baseInfo'
import { NzMessageService } from 'ng-zorro-antd'
import { I18NService } from '@core'
import { ACLService } from '@delon/acl'
import { objectArrayDeduplication } from 'app/utils/helpers'

@Component({
  selector: 'app-acquirer-detail-tab-audit',
  templateUrl: './tab-audit.component.html',
  styleUrls: ['./tab-audit.component.less'],
})
export class AcquirerDetailTabAuditComponent extends DetailTabClass<AuditConfig[]> implements OnInit {
  @ViewChild('tradeOperate') tradeOperate: TemplateRef<void>

  @ViewChild('tplExchange') tplExchange: TemplateRef<void>
  @ViewChild('tplRiskControl') tplRiskControl: TemplateRef<void>
  @ViewChild('tplStore') tplStore: TemplateRef<void>
  @ViewChild('tplTransRefund') tplTransRefund: TemplateRef<void>
  @ViewChild('tplSwitchAudit') tplSwitchAudit: TemplateRef<void>
  @ViewChild('tplOperation') tplOperation: TemplateRef<void>

  fields = {
    AuditConfig: '1',
  }
  stepRange = [1, 2, 3, 4, 5, 6, 7, 8, 9]
  params: IUpdateAcquirerAudit
  insCode: string
  auditConfigType = EAuditConfigType
  defaultAuditConfig = [
    // { type: EAuditConfigType.ExchangeRate, stepNumber: 0 },
    { type: EAuditConfigType.RiskControl, stepNumber: 0 },
    { type: EAuditConfigType.Store, stepNumber: 0 },
    { type: EAuditConfigType.TransRefund, stepNumber: 0 },
    { type: EAuditConfigType.Operation, stepNumber: 0 },
  ]
  swAuditStatus: { [key: string]: boolean } = {}
  isShow: Boolean = true

  constructor(
    public pageService: PageService,
    private messageService: NzMessageService,
    private commonAcquirerService: CommonAcquirerService,
    private acquirerService: AcquirerService,
    public aclService: ACLService,
    public route: ActivatedRoute,
    private i18n: I18NService,
  ) {
    super(pageService, route)
  }

  ngOnInit() {
    this.initialData()
  }

  initialData() {
    this.commonAcquirerService.viewAcquirer$.value$.subscribe(acquirer => {
      this.initialColumns()
      let auditConfigs = acquirer.institution.common.auditConfigs || []
      if (auditConfigs) {
        // Because backend requirer cost in get 'steps' from "updateBaseInfoOfAcquirer" api. Workaround check step else get stepNumber
        auditConfigs = objectArrayDeduplication(auditConfigs, 'type')
        auditConfigs.forEach(
          auditConfig => {
            auditConfig['stepNumber'] = auditConfig.steps ? auditConfig.steps.length : auditConfig.stepNumber
          })
      }
      this.manageAuditData(auditConfigs)
      this.params = {
        version: acquirer.institution.version,
        auditConfigs: this.data,
      }
      this.setEdit(this.fields.AuditConfig, 1)
      this.setupAuditConfigColumn(this.data)
      this.setupIdForColumn(this.fields)
    })
    this.pageService.setTabScrollStatus(ETabScrollStatus.Scroll)
  }

  manageAuditData(auditConfigs: AuditConfig[]) {
    // Since backend never return audit with stepNumber 0, so frontend need to added in and display in the UI
    this.defaultAuditConfig.forEach(defaultAuditConfig => {
      if (auditConfigs.findIndex(auditConfig => auditConfig.type === defaultAuditConfig.type) >= 0) {
        return
      }
      auditConfigs.push({
        steps: [],
        type: defaultAuditConfig.type,
        stepNumber: defaultAuditConfig.stepNumber,
      })
    })
    this.data = auditConfigs
  }

  setupAuditConfigColumn(auditConfigs: AuditConfig[]): void {
    let isSetupAudit: boolean
    const setupAuditConfig = []

    // "开通审核功能": "开" when either one of the auditConfig.stepNumber > 0.
    const isMainAuditEdit = this.isAudit()
    for (const auditConfig of auditConfigs) {
      if (auditConfig.stepNumber > 0) {
        isSetupAudit = true
      } else {
        isSetupAudit = false
      }
      // 如果其中一个stepNumber > 0 的话就是"开" if (auditConfig.stepNumber > 0) { isSetupAudit = true } else { isSetupAudit = false }

      this.swAuditStatus[auditConfig.type] = isSetupAudit

      switch (auditConfig.type) {
        case EAuditConfigType.Store: {
          setupAuditConfig.push({
            span: 4,
            // label: '门店录入审核层级',
            label: this.trans('AUDIT.LEVEL', { name: this.trans('AUDIT.LEVEL.STORE') }),
            value: auditConfig.stepNumber,
            index: auditConfig.type,
            template: this.tplStore,
            disEditable: auditConfig.stepNumber > 0 || !isMainAuditEdit,
            position: 0,
          })
          continue
        }
        case EAuditConfigType.TransRefund: {
          setupAuditConfig.push({
            span: 4,
            // label: '机构退款审核层级',
            label: this.trans('AUDIT.LEVEL', { name: this.trans('AUDIT.LEVEL.TRANSREFUND') }),
            value: auditConfig.stepNumber,
            index: auditConfig.type,
            template: this.tplTransRefund,
            disEditable: auditConfig.stepNumber > 0 || !isMainAuditEdit,
            position: 1,
          })
          continue
        }
        case EAuditConfigType.Operation: {
          setupAuditConfig.push({
            span: 4,
            // label: '运营审核层级',
            label: this.trans('AUDIT.LEVEL', { name: this.trans('AUDIT.LEVEL.OPERATION') }),
            value: auditConfig.stepNumber,
            index: auditConfig.type,
            template: this.tplOperation,
            disEditable: auditConfig.stepNumber > 0 || !isMainAuditEdit,
            position: 2,
          })
          continue
        }
        // case EAuditConfigType.ExchangeRate: {
        //   setupAuditConfig.push({
        //     span: 4,
        //     label: '门店汇率审核层级',
        //     value: auditConfig.stepNumber,
        //     index: auditConfig.type,
        //     template: this.tplExchange,
        //     disEditable: auditConfig.stepNumber > 0 || !isMainAuditEdit,
        //     position: 2
        //   })
        //   continue
        // }
        case EAuditConfigType.RiskControl: {
          setupAuditConfig.push({
            span: 4,
            // label: '风控方案审核层级',
            label: this.trans('AUDIT.LEVEL', { name: this.trans('AUDIT.LEVEL.RISKCONTROL') }),
            value: auditConfig.stepNumber,
            index: auditConfig.type,
            template: this.tplRiskControl,
            disEditable: auditConfig.stepNumber > 0 || !isMainAuditEdit,
            position: 3,
          })
          continue
        }
      }
    }
    // 排版Audit
    setupAuditConfig.sort((a, b) => (a.position > b.position ? 1 : -1))
    // Push item in front
    setupAuditConfig.unshift({
      span: 4,
      label: '开通审核功能',
      labelI18n: 'AUDIT.ACQUIRER.OPEN_AUDIT_CONFIG',
      value: isMainAuditEdit,
      displayValue: isMainAuditEdit ? this.trans('AUDIT.STATUS.OPEN') : this.trans('AUDIT.STATUS.CLOSED'),
      disEditable: isMainAuditEdit,
      template: !isMainAuditEdit ? this.tplSwitchAudit : null,
    })
    // TODO:优化ACL
    const canOperate = this.aclService.canAbility('api.put.camel.institution.one.audit')
    if (canOperate && this.isOperate()) {
      setupAuditConfig.push({
        span: 4,
        label: 'GENERAL.INFO.OPERATION',
        labelI18n: 'GENERAL.INFO.OPERATION',
        operate: true,
        template: this.tradeOperate,
      })
    }
    this.columns[this.fields.AuditConfig].push(setupAuditConfig)
  }

  onChangeMainAudit(value: boolean) {
    for (const audits of this.columns[this.fields.AuditConfig]) {
      for (const column of audits) {
        if (!column.index) continue
        column.disEditable = !value
      }
    }
  }

  isAudit(): boolean {
    return this.data.findIndex(audit => audit.stepNumber > 0) >= 0
  }
  // 操作栏是否显示 true(显示) false(隐藏)
  isOperate(): boolean {
    return !this.data.every(audit => audit.stepNumber > 0)
  }

  // abstract methods
  onCancel() {
    this.columns[this.field][this.rowIndex].forEach(column => {
      // 这个是开通审核功能
      if (!column.index) {
        column.value = this.isAudit()
        return
      }
      const index = this.data.findIndex(item => item.type === column.index)
      column.value = this.data[index].stepNumber
      this.swAuditStatus[column.index] = column.value > 0
    })
  }

  onSubmit() {
    try {
      this.columns[this.field][this.rowIndex].forEach(column => {
        if (!column.index) return
        if (!this.swAuditStatus[column.index]) {
          column.value = 0
        }
        const index = this.data.findIndex(item => item.type === column.index)
        this.data[index].stepNumber = column.value as number
      })

      // Remove stepNumber 0 from data
      const requestBody = this.data.filter(auditConfig => auditConfig.stepNumber !== 0)
      // Get insCode from path
      const insCode = this.route.parent.snapshot.params.id
      this.params.auditConfigs = requestBody
      this.acquirerService.updateAuditOfAcquirer(this.params, insCode).subscribe(
        acquirer => {
          this.commonAcquirerService.setViewingAcquirer(acquirer)
          // // Once update audit, disable the '开通审核功能'
          // const index = this.columns[this.field][this.rowIndex].findIndex(item => item.label === '开通审核功能')
          // this.columns[this.field][this.rowIndex][index].disEditable = true
          if (!this.isOperate()) {
            this.isShow = !this.isShow
          }
          this.messageService.success(this.trans('GENERAL.NOTIFICATION.UPDATE_SUCCESS'))
        },
        err => {
          this.messageService.error(this.trans('GENERAL.NOTIFICATION.UPDATE_FAIL'))
        },
      )
    } catch (error) {
      this.messageService.error(this.trans('GENERAL.NOTIFICATION.UPDATE_FAIL'))
    }
  }

  initialColumns() {
    /*
     * 这个columns是用来收集所有需要display在这个tab里面的数据.
     * 比如 "交易币种转换" = '1', 然后交易币种转换里有一个Array = [商户交易币种, 转换交易币种, 转换汇率, 等等] 然后他在columns里就是
     * {'1': [[{商户交易币种, 转换交易币种, 转换汇率, 等等}]]}
     */
    // 现在这个trades component需要展示2个field. 这里创建2个空的Array在this.columns里的field
    for (const key in this.fields) {
      this.columns[this.fields[key]] = []
    }
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
